package com.ecentraltech.maven.plugins;

/*
 * Copyright 2011 eCentral Technologies LLC
 *
 */
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;

/**
 * Goal to populate a bat file with a classpath for running
 * Java programs via the command line
 *
 * @goal batch-classpath
 * 
 * @phase install
 */
public class BatchClasspath extends AbstractMojo
{
    /**
     * Location of the file.
     * @parameter expression="${project.build.directory}"
     * @required
     */
    private File outputDirectory;

    /**
     * Name of the file resulting from execution.
     * @parameter expression="${output.filename}" default-value="SetEnv.bat"
     * @required
     */
    private String outputFilename;

    /**
     * Location of template files.
     * @parameter expression="${template.directory}" default-value="templates"
     * @required
     */
    private String templateDirectory;

    /**
     * Name of the template file.
     * @parameter expression="${template.filename}" default-value="_SetEnv.template"
     * @required
     */
    private String templateFilename;
    
    /** @parameter default-value="${project}" */
    private MavenProject project;

    public void execute() throws MojoExecutionException {
        File template = new File(templateDirectory, templateFilename);
        BufferedReader templateReader;
        try {
            templateReader = new BufferedReader(new FileReader(template));
        }
        catch ( IOException e ) {
            throw new MojoExecutionException("Invalid/Missing template file: " + template.getAbsolutePath());
        }
                
        File outDirectory = outputDirectory;
        getLog().info("Output directory: " + outDirectory.getAbsolutePath());

        if ( !outDirectory.exists() ) {
            outDirectory.mkdirs();
        }

        File outputFile = new File( outDirectory, outputFilename );
        FileWriter outputWriter = null;
        try {
            outputWriter = new FileWriter(outputFile);

            for (;;) {
                String line = templateReader.readLine();
                if (line == null) {
                    break;
                }
                else {
                    if (line.startsWith("<classpath")) {
                        writeClasspath(line, outputWriter);
                    }
                    else {
                        outputWriter.write(line);
                        outputWriter.write("\n");
                    }
                }
            }
        }
        catch ( IOException e ) {
            throw new MojoExecutionException( "Error writing to: " + outputFile.getAbsolutePath(), e );
        }
        finally {
            if (templateReader != null) {
                try {
                    templateReader.close();
                }
                catch ( IOException e ) {
                    // ignore
                }
            }
            if ( outputWriter != null ) {
                try {
                    outputWriter.close();
                }
                catch ( IOException e ) {
                    // ignore
                }
            }
        }
    }
    
    private void writeClasspath(String line, FileWriter outputWriter) throws IOException {
        
        //<classpath line="set CLSPATH=%CLSPATH%;%APPPATH%\lib\${artifact}" />
        int begOffset = line.indexOf("line=");
        if (begOffset < 0){
            //no output
            return;
        }

        begOffset += 6;
        int endOffset = line.indexOf("\"", begOffset);
        if (begOffset < 0){
            //no output
            return;
        }

        String format = line.substring(begOffset, endOffset);
        
        if (project != null){
            List artifacts = null;
            try {
                //write this projects reference
                outputWriter.write(format.replace("${artifact}", project.getArtifact().getFile().getName()));
                outputWriter.write("\n");
                
                //write all of the dependencies
                artifacts = project.getCompileClasspathElements();
                for (Iterator artifactIterator = artifacts.iterator(); artifactIterator.hasNext();) {
                  String artifact = (String) artifactIterator.next();
                  String[] artifactPath = artifact.split("\\\\");
                  String fileName = artifactPath[artifactPath.length - 1];
                  if (fileName.endsWith(".jar")){
                      outputWriter.write(format.replace("${artifact}", fileName));
                      outputWriter.write("\n");
                  }
                  else {
                      getLog().warn("On classpath: " + artifact);
                  }
                }
            } catch (DependencyResolutionRequiredException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

//            Set artifacts = project.getDependencyArtifacts();
//            for (Iterator artifactIterator = artifacts.iterator(); artifactIterator.hasNext();) {
//              Artifact artifact = (Artifact) artifactIterator.next();
//              try {
//                  outputWriter.write(format.replace("${artifact}", artifact.getFile().getName()));
//                  outputWriter.write("\n");
//              }
//              catch (Exception e) {
//                  getLog().error("Unable to write classpath entry for " + artifact.getArtifactId(), e);
//                  outputWriter.write("oops... see error log\n");
//              }
//            }
        }
    }
}
